/*
 * @Author: 李超越 1509572300@qq.com
 * @Date: 2024-07-23 18:49:49
 * @LastEditors: 李超越 1509572300@qq.com
 * @LastEditTime: 2024-07-24 13:25:37
 * @FilePath: /my_git/lesson23_buffer/mystdio.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

#include "mystdio.h"

const char* toString(int flag)
{
    if(flag & NONE_FLUSH)
    {
        return "None";
    }
    else if(flag & LINE_FLUSH)
    {
        return "Line";
    }
    else if(flag & FULL_FLUSH)
    {
        return "FULL";
    }
    return "unknow";
}

void DebugPrint(myFILE* fp)
{
    printf("outbuffer:%s\n",fp->outbuffer);
    printf("fd:%s\n",fp->fileno);
    printf("pos:%s\n",fp->pos);
    printf("cap:%s\n",fp->cap);
    printf("flush_mode:%s\n",toString(fp->flush_mode&LINE_FLUSH));
}

myFILE* my_fopen(const char* pathname,const char*mode)
{
    int flag=0;
    if(strcmp(mode,"r")==0)
    {
        flag|=O_RDONLY;
    }
    else if(strcmp(mode,"w")==0)
    {
        flag|=(O_CREAT|O_WRONLY|O_TRUNC);
    }
    else if(strcmp(mode,"a")==0)
    {
        flag|=(O_CREAT|O_WRONLY|O_APPEND);
    }
    else
    {
        return NULL;
    }
    int fd=0;
    if(flag&O_WRONLY)
    {
        umask(0);
        fd=open(pathname,flag,0666);
        if(fd<0)
        {
            return NULL;
        }
    }
    else
    {
        fd=open(pathname,0666);
    }
    if(fd<0)
    {
        return NULL;
    }
    myFILE* fp=(myFILE*)malloc(sizeof(myFILE));
    if(fp==NULL)
    {
        return NULL;
    }
    fp->fileno=fd;
    fp->cap=SIZE;
    fp->pos=0;
    return fp;
}

void my_fflush(myFILE* fp)
{
    if(fp->pos==0)
    {
        return ;
    }
    write(fp->fileno,fp->outbuffer,fp->pos);
    fp->pos=0;
}

int my_fwrite(myFILE *fp,const char *s,int size)
{
    memcpy(fp->outbuffer+fp->pos,s,size);
    fp->pos+=size;
    if((fp->flush_mode & LINE_FLUSH) && fp->outbuffer[fp->pos-1] == '\n')
    {
        my_fflush(fp);
    }
    else if((fp->flush_mode & FULL_FLUSH) && fp->pos == fp->cap)
    {
        my_fflush(fp);
    }
    return size;
}

void my_close(myFILE* fp)
{
    close(fp->fileno);
    free(fp);
}
